package com.zhaungjie.base.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * BigDecimal工具
 *
 * @author zhuangjie
 * @date 2023/10/30
 */
public class BigDecimalUtils {
    /**
     * 保留的小数点位数
     */
    private final int SCALE;
    /**
     * 舍入模式
     */
    private final RoundingMode roundingMode;


    public BigDecimalUtils(int SCALE, RoundingMode roundingMode) {
        this.SCALE = SCALE;
        this.roundingMode = roundingMode;
    }

    public BigDecimalUtils() {
        this.SCALE = 2;
        this.roundingMode = RoundingMode.DOWN;
    }

    /**
     * 创建零的BigDecimal
     *
     * @return {@link BigDecimal}
     */
    public BigDecimal createZeroBigDecimal() {
        BigDecimal result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 修剪为需要的小数位
     *
     * @param bigDecimals 大小数
     * @return {@link BigDecimal}
     */
    public BigDecimal trimDecimalPlaces(BigDecimal bigDecimals) {
        if (bigDecimals == null) return null;
        return bigDecimals.setScale(SCALE, roundingMode);
    }


    /**
     * 加法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行加法运算
     * 乘法过去，还是null,返回0
     * @param bigDecimals
     * @return
     */
    public BigDecimal additionOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null?bigDecimal:result.add(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 减法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行减法运算
     * 乘法过去，还是null,返回0
     * @param bigDecimals
     * @return
     */
    public BigDecimal subtractionOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null?bigDecimal:result.subtract(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 除法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行乘法运算
     * 乘法过去，还是null,返回0
     * @param bigDecimals
     * @return
     */
    public BigDecimal division(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null?bigDecimal:result.divide(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 乘法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行乘法运算
     * 乘法过去，还是null,返回0
     * @param bigDecimals
     * @return
     */
    public BigDecimal multiplicationOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null?bigDecimal:result.multiply(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }



}
